<?php
require_once __DIR__.'/../../'.'bootstrap.php';
/**
 * 失联修复接口
 * @author 韦锦国
 * 2019-09-2
 * UTF-8
 */
class Lib_Request_RepairContact
{
    private static $obj = null;
    //conf配置
    private static $conf = array(
        'send' => array(
            'appid' => 'test_dcpASend',
            'apiid' => 'dcpAccurateSend',
            'key' => 'f11e96848c7e2d1ab97238d57da277a5',
        ),
        'query' => array(
            'appid' => 'test_dcpAQuery',
            'apiid' => 'dcpAccurateQuery',
            'key' => '2f22361110f4ba93325dd517b94d7323',
        ),
    );
    private static $apiUrl  = "http://125.88.169.221:8081/openapi/repair";


    /**
     * 获取单例对象
     * @param string $hl
     * @param number $timeout
     * @return Lib_Request_RepairContact
     */
    public static function getInstance()
    {
        if (is_null(self::$obj)) {
            self::$obj = new self();
        }

        return self::$obj;
    }
    //获取随机字符串
    public static function getNonce(){
        mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        return $charid;
    }
    //获取毫秒时间戳
    private static function getMillisecond(){
        list($msec, $sec) = explode(' ', microtime());
        $msectime =  (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        return $msectimes = substr($msectime,0,13);
    }
    //获取请求头
    private static function getHeader($type){
        $timestamp = self::getMillisecond();
        $nonce = self::getNonce();
        return array(
            'appid:'.self::$conf[$type]['appid'],
            'apiid:'.self::$conf[$type]['apiid'],
            'timestamp:'.$timestamp,
            'nonce:'.$nonce,
            'sign:'.md5(self::$conf[$type]['appid'].self::$conf[$type]['apiid'].self::$conf[$type]['key'].$timestamp.$nonce),
        );
    }
    //解成16进制
    private static function Hex2String($hex){
        $string='';
        for ($i=0; $i < strlen($hex)-1; $i+=2){
            $string .= chr(hexdec($hex[$i].$hex[$i+1]));
        }
        return $string;
    }

    //加密
    private static function encrypt($data,$key) {
        $data =  openssl_encrypt($data, 'aes-128-ecb', self::Hex2String($key), OPENSSL_RAW_DATA);
        return base64_encode($data);
    }
   //解密
    private static function decrypt($data,$key) {
        $encrypted = base64_decode($data);
        return openssl_decrypt($encrypted, 'aes-128-ecb',  self::Hex2String($key), OPENSSL_RAW_DATA);
    }
    //curl 请求
    private static function postjson($url, $params = '', $json_header,$timeout = 30)
    {
        $logs = ' request_url='.$url;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_NOBODY, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge(array('Content-Type:application/json;charset=utf-8'),$json_header));
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);

        $log = array();
        $res = curl_exec($ch);
        $log['errno'] = curl_errno($ch);
        if ($log['errno'] !== 0) {
            curl_close($ch);
            $result['error'] = $log['errno'];
            Func_Log::write('curl_postjson', 'curl_response401', $logs.json_encode($log).$res);

            return $result;
        }
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        curl_close($ch);
        $return = array();
        $headArr = explode("\r\n", substr($res, 0,$header_size));
        foreach ($headArr as $loop) {
            if(strpos($loop, "status") !== false){
                $return['status'] = trim(explode(":", $loop)[1]);
            }
            if(strpos($loop, "msg") !== false){
                $return['msg'] = trim(explode(":", $loop)[1]);
            }
        }
        if (isset($return['status']) && $return['msg'] && $return['status'] == 0 ){
            $return['body'] = json_decode(substr($res, $header_size),true)['body'];
        }

        $return['error'] = 200;
        return $return;
    }
    /*
    * 请求接口
    */
    public function
    request( $data = [], $type = 'send')
    {
        //初始化日志
        $header = self::getHeader($type);
        $logs = 'type= '.$type;
        $logs .= ' header= '.json_encode($header);
        $logs .= ' data= '.json_encode($data);
        //参数加密
        $params = self::encrypt(json_encode($data),self::$conf[$type]['key']);
        $params = json_encode(array('body'=>$params));
        $logs .= ' encryptData= '.$params;
        //请求接口
        $result = self::postjson(self::$apiUrl, $params, $header);
        if($result['error'] != 200 || !isset($result['body']) || !in_array($result['status'], array(0,1)) ){
            Func_Log::write('RepairContact', 'REQUEST', 'return error '.$logs." return=".json_encode($result));
            return $result;
        }
        if($result['status'] == 0){
            //body解密
            $body = self::decrypt($result['body'],self::$conf[$type]['key']);
            if (!$body){
                Func_Log::write('RepairContact', 'REQUEST', 'decrypt error '.$logs." return=".json_encode($result));
                return $result;
            }
            $result['body'] = json_decode($body,true);
        }
        Func_Log::write('RepairContact', 'REQUEST', $logs." return=".json_encode($result));
        return $result;

    }
}
